package com.tv.cms.payorderinfo.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.tv.cms.deviceInfo.model.DeviceInfo;
import com.tv.cms.deviceInfo.service.DeviceInfoService;
import com.tv.cms.goods.model.Goods;
import com.tv.cms.goods.service.GoodsService;
import com.tv.cms.payorderinfo.model.PayOrderInfo;
import com.tv.cms.payorderinfo.service.PayOrderInfoService;
import com.tv.cms.system.account.model.Account;
import com.tv.cms.system.account.service.AccountService;
import com.tv.cms.system.admin.model.Admin;
import com.tv.cms.system.admin.service.AdminService;
import com.tv.cms.authcode.model.AuthCode;
import com.tv.cms.system.operator.model.Operator;
import com.tv.cms.system.operator.model.OperatorConfig;
import com.tv.cms.system.operator.model.PreCreateResultVO;
import com.tv.cms.authcode.service.AuthCodeService;
import com.tv.cms.system.operator.service.OperatorConfigService;
import com.tv.cms.system.operator.service.OperatorService;
import com.tv.cms.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * TODO
 *
 * @author
 * @date
 **/
@RestController
@RequestMapping("order")
public class PayOrderInfoController {

    @Resource
    private PayOrderInfoService service;
    @Resource
    private AdminService adminService;
    @Resource
    private OperatorService operatorService;
    @Resource
    private AccountService accountService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private OperatorConfigService operatorConfigService;
    @Resource
    private AuthCodeService authCodeService;
    @Autowired
    private DeviceInfoService deviceInfoService;

    @PostMapping("list")
    public Result<Page<PayOrderInfo>> list(@RequestBody PayOrderInfo payOrderInfo){
        Admin admin = adminService.getById(StpUtil.getLoginIdAsInt());
        StringBuffer operatorIds = new StringBuffer();
        if(admin.getRoleId() == 2 || admin.getRoleId() == 3 || admin.getRoleId() == 5) {
            List<Operator> oplist = operatorService.list(new QueryWrapper<Operator>().eq("create_by",admin.getId()));
            if(admin.getRoleId() == 2 ){
                operatorService.dataList(operatorIds,admin.getId());
            }
            for(Operator opp : oplist) {
                operatorIds.append(opp.getId()).append(",");
            }
            if(admin.getRoleId() == 3){
                operatorIds.append(admin.getOperatorId()).append(",");
            }
            if(admin.getRoleId() == 5 ) {
                operatorIds.append(admin.getOperatorId()).append(",");
            }
            if(StringUtils.isNotBlank(operatorIds) && operatorIds.length() > 0) {
                operatorIds = new StringBuffer(operatorIds.substring(0, operatorIds.length() - 1));
            }
        }
       /* if(admin.getRoleId() == 3 ) {
            payOrderInfo.setOperatorId(admin.getOperatorId());
        }
        if(admin.getRoleId() == 5 ) {
            payOrderInfo.setOperatorId(operatorService.getById(admin.getOperatorId()).getParentId());
        }*/

        String apply = "";
        if(operatorIds.length()>0){
            apply = "(t.operator_id in ("+operatorIds+") or t.create_by = "+ StpUtil.getLoginIdAsInt()+")";
        }else {
            if(admin.getRoleId() != 1){
                apply = "t.create_by = "+ StpUtil.getLoginIdAsInt();
            }
        }
        if(payOrderInfo.getOperatorId() != null){
            apply = "(t.create_by = " + StpUtil.getLoginIdAsInt() + " or t.operator_id =" + payOrderInfo.getOperatorId() + ")";
        }
        MPJLambdaWrapper<PayOrderInfo> wrapper = new MPJLambdaWrapper<PayOrderInfo>();
        wrapper.selectAll(PayOrderInfo.class);
        wrapper.selectAs("t1.user_name", PayOrderInfo:: getCreateName);
        wrapper.leftJoin(Admin.class, Admin :: getId, PayOrderInfo :: getCreateBy);
        wrapper.selectAs("t2.user_name", PayOrderInfo:: getUpdateName);
        wrapper.leftJoin(Admin.class, Admin :: getId, PayOrderInfo :: getUpdateBy);
        wrapper.selectAs("t3.name", PayOrderInfo:: getOperatorName);
        wrapper.leftJoin(Operator.class, Operator :: getId, PayOrderInfo :: getOperatorId);
        wrapper.selectAs("t4.days", PayOrderInfo:: getDays);
        wrapper.selectAs("t4.name", PayOrderInfo:: getGoodsName);
        wrapper.leftJoin(Goods.class,  Goods :: getId,PayOrderInfo :: getGoodsId);
        wrapper.eq(payOrderInfo.getStatus() != null,  PayOrderInfo :: getStatus,payOrderInfo.getStatus());
        wrapper.like(StringUtils.isNotBlank(payOrderInfo.getOrderNo() ),  PayOrderInfo :: getOrderNo,payOrderInfo.getOrderNo());
        wrapper.like(StringUtils.isNotBlank(payOrderInfo.getMac() ),  PayOrderInfo :: getMac,payOrderInfo.getMac());
        wrapper.like(StringUtils.isNotBlank(payOrderInfo.getOperatorName()), Operator::getName,payOrderInfo.getOperatorName());
      //  wrapper.in(payOrderInfo.getServiceTypes() != null && !payOrderInfo.getServiceTypes().isEmpty(), PayOrderInfo :: getServiceType,payOrderInfo.getServiceTypes());
        wrapper.like(org.springframework.util.StringUtils.hasText(payOrderInfo.getCreateName()), "t1.user_name", payOrderInfo.getCreateName());
        wrapper.apply(apply.length()>0, apply);
        if(admin.getRoleId() == 5){
            wrapper.apply("(select role_id from admin where id = t.create_by) != 2");
        }
                //.in(operatorIds.length()>0, PayOrderInfo :: getOperatorId,operatorIds)
                //.eq(payOrderInfo.getOperatorId() != null,PayOrderInfo :: getOperatorId,payOrderInfo.getOperatorId())
        wrapper.orderByDesc(PayOrderInfo :: getStatus,PayOrderInfo :: getCreateTime);
        Page<PayOrderInfo> page = service.selectJoinListPage(new Page<>(payOrderInfo.getPage(), payOrderInfo.getLimit()), PayOrderInfo.class, wrapper);


        //查询账户余额和免费套餐剩余额度
        Account account =  accountService.getOne(new QueryWrapper<Account>().eq("operator_id",admin.getOperatorId()));
        BigDecimal balance = account != null ? new BigDecimal( account.getBalance()) : new BigDecimal(0);
        page.setCountId(balance.toString());
        Result<Page<PayOrderInfo>> result = new Result<>();
        return result.OKDATA(page);
    }
    @PostMapping("list2")
    public Result<Page<PayOrderInfo>> list2(@RequestBody PayOrderInfo payOrderInfo){
        Admin admin = adminService.getById(StpUtil.getLoginIdAsInt());
        payOrderInfo.setCreateBy(StpUtil.getLoginIdAsInt());
        List<PayOrderInfo> list = service.list(payOrderInfo);
        int count = service.count(payOrderInfo);
        Page<PayOrderInfo> page =new Page<>();
        page.setRecords(list);
        page.setTotal(count);
        page.setCurrent(payOrderInfo.getPage());
        page.setSize(payOrderInfo.getLimit());
        Account account =  accountService.getOne(new QueryWrapper<Account>().eq("operator_id",admin.getOperatorId()));
        BigDecimal balance = account != null ? new BigDecimal( account.getBalance()) : new BigDecimal(0);
        page.setCountId(balance.toString());
        Result<Page<PayOrderInfo>> result = new Result<>();
        return result.OKDATA(page);
    }
    @PostMapping("save")
    public Result<Object> save(@RequestBody PayOrderInfo payOrderInfo){
        payOrderInfo.setCreateBy(StpUtil.getLoginIdAsInt());
        payOrderInfo.setCreateTime(new Date());
        payOrderInfo.setUpdateBy(StpUtil.getLoginIdAsInt());
        payOrderInfo.setUpdateTime(new Date());
        payOrderInfo.setStatus(1);
        boolean b = service.save(payOrderInfo);
        return b ? Result.OK() : Result.FAILURE();
    }

    /**
     * 更新订单
     * @param payOrderInfo
     * @return
     */
    @PutMapping("status")
    public Result status(@RequestBody PayOrderInfo payOrderInfo){
        PayOrderInfo r = new PayOrderInfo();
        r.setId(payOrderInfo.getId());
        r.setStatus(payOrderInfo.getStatus());
        boolean b = service.updateById(r);
        return b ? Result.OK() : Result.FAILURE();
    }

    @PutMapping("updateDeviceStatus")
    public Result updateStatus(@RequestBody PayOrderInfo payOrderInfo){
        DeviceInfo deviceInfo = new DeviceInfo();
        deviceInfo.setId(payOrderInfo.getDeviceId());
        deviceInfo.setStatus(payOrderInfo.getDeviceStatus());
        boolean b = deviceInfoService.updateDeviceStatus(deviceInfo);
        return b ? Result.OK() : Result.FAILURE();
    }
    @PutMapping("updateComment")
    public Result updateComment(@RequestBody PayOrderInfo payOrderInfo){
        PayOrderInfo r = new PayOrderInfo();
        r.setId(payOrderInfo.getId());
        r.setComment(payOrderInfo.getComment());
        boolean b = service.updateById(r);
        return b ? Result.OK() : Result.FAILURE();
    }

    /**
     * 充值
     * @param payOrderInfo
     * @return
     */
    @PostMapping("recharge")
    public Result recharge(@RequestBody PayOrderInfo payOrderInfo, HttpServletRequest request){
        Admin admin = adminService.getById(StpUtil.getLoginIdAsInt());
        if(admin.getRoleId() != 2 && admin.getRoleId() != 3) {
            return Result.FAILURE("非销售角色和上级经销商不能给经销商充值！");
        }
        Operator operator = operatorService.getById(payOrderInfo.getOperatorId());
        IDGenerator Id1 = new IDGenerator(1);
        String orderNo = 2 + TimeUtils.converStringDate(new Date(), "yyMMdd") + Id1.nextId();
        long count = service.count(new QueryWrapper<PayOrderInfo>().eq("order_no", orderNo));
        // 判断订单号是否重复
        while (count > 0) {
            count = service.count(new QueryWrapper<PayOrderInfo>().eq("order_no", orderNo));
        }
        PayOrderInfo order = new PayOrderInfo();
        order.setServiceType(2);
        order.setGoodsId(0);
        order.setGoodsNum(0);
        order.setMoney(payOrderInfo.getMoney());
        order.setBalance("0");
        order.setOrderNo(orderNo);
        order.setCreateTime(new Date());
        /** 订单状态（-1：未支付，0:支付成功，1已退款） */
        order.setStatus(0);
        /** (0：默认初始值，1支付失败，2退款失败，3申请退款) */
        order.setDetailState(0);
        order.setOperatorId(payOrderInfo.getOperatorId());// 默认

        //查询用户账户余额（金币）
        BigDecimal balance = BigDecimal.valueOf(0);
        Account account = accountService.getOne(new QueryWrapper<Account>().eq("operator_id",payOrderInfo.getOperatorId()));
        String goodsrate = "0";
        if(operator != null && operator.getGoldrate() != null) {
            goodsrate = operator.getGoodsrate();
        }
        Integer three = account!=null ? account.getThree() : operator.getThree();
        Integer seven = account!=null ? account.getSeven() : operator.getSeven();
        Integer thirty = account!=null ? account.getThirty() : operator.getThirty();
        Account account1 = accountService.getOne(new QueryWrapper<Account>().eq("operator_id", admin.getOperatorId()));

        Double sub;
        if(admin.getRoleId() == 2){
//sub = BigDecimalUtils.add(Double.parseDouble(account1.getBalance()), BigDecimalUtils.round(Double.parseDouble(payOrderInfo.getMoney()) / (1 + Float.parseFloat(goodsrate)), 0));
            sub = BigDecimalUtils.add(Double.parseDouble(account1.getBalance()), BigDecimalUtils.round(Double.parseDouble(payOrderInfo.getMoney()) , 0));
        }else{
             sub = BigDecimalUtils.sub(Double.parseDouble(account1.getBalance()), BigDecimalUtils.round(Double.parseDouble(payOrderInfo.getMoney()) / (1 + Float.parseFloat(goodsrate)), 0));
            if(sub < 0){
                return Result.FAILURE (500, "余额不足!");
            }
        }
        account1.setBalance(sub.toString());
        accountService.updateById(account1);

        if(account == null){
         //   balance = BigDecimal.valueOf(BigDecimalUtils.round(Double.parseDouble(payOrderInfo.getMoney())*(1+Float.parseFloat(goodsrate)), 2));
            balance = new BigDecimal(payOrderInfo.getMoney());
            account = new Account();
            account.setOperatorId(payOrderInfo.getOperatorId());
            account.setBalance(balance.toString());
            account.setFreezeMoney("0");
            account.setCreateTime(new Date());
            account.setThree(three);
            account.setSeven(seven);
            account.setThirty(thirty);
            accountService.save(account);

        }else {
           // balance = BigDecimal.valueOf(BigDecimalUtils.add(Double.parseDouble(account.getBalance()), BigDecimalUtils.round(Double.parseDouble(payOrderInfo.getMoney())/(1+Float.parseFloat(goodsrate)), 2)));
            balance = BigDecimal.valueOf(BigDecimalUtils.add(Double.parseDouble(account.getBalance()), BigDecimalUtils.round(Double.parseDouble(payOrderInfo.getMoney()), 0)));
            account.setBalance(balance.toString());
            accountService.updateById(account);

        }

        order.setComment(goodsrate+"");
        order.setBalance(balance.toString());
        order.setCreateBy(StpUtil.getLoginIdAsInt());
        order.setOperateIp(HttpRequestUtils.getIpAddr(request));
        //支付渠道(0.线下支付，1支付宝，2微信支付3贝宝支付4余额支付)
        order.setChannels(0);
        order.setPayTime(new Date());
        boolean b = service.save(order);
        return b ? Result.OK() : Result.FAILURE("提交订单失败");
    }
    @PostMapping("placeOrder")
    public Result placeOrder(@RequestBody PayOrderInfo payOrderInfo, HttpServletRequest request){
        if(StringUtils.isNotBlank(payOrderInfo.getMac()) && StringUtils.isNotBlank(payOrderInfo.getSn())) {
            int i = deviceInfoService.selectCount(new LambdaQueryWrapper<DeviceInfo>().eq(DeviceInfo::getMac, payOrderInfo.getMac()));
            if (i > 0) {
                return Result.FAILURE(500, "账号：" + payOrderInfo.getMac() + " 已存在!");
            }
        }
        Admin admin = adminService.getById(StpUtil.getLoginIdAsInt());
        if(admin.getRoleId() != 5 && admin.getRoleId() != 3) {
            return Result.FAILURE("非经销商角色不能购买商品！");
        }
        //serviceType 订单服务类型：1.app充值;2.后台充值;3.购买商品
        Double price = 0.0;

        Goods goods =  goodsService.getById(payOrderInfo.getGoodsId());
        price =Double.parseDouble( goods.getPrice());
        Operator operator = operatorService.getById(admin.getOperatorId());
        if(admin.getRoleId() == 5){
            OperatorConfig occ = operatorConfigService.getOne(new QueryWrapper<OperatorConfig>().eq("goods_id", goods.getId()).eq("operator_id", admin.getOperatorId()));
            if(occ != null) {
                price = BigDecimalUtils.round(Double.parseDouble(goods.getPrice())*(1+ Float.parseFloat(operator.getGoodsrate())), 2);
            }
        }
        Double amount = BigDecimalUtils.mul(price, payOrderInfo.getGoodsNum());
        //查询用户账户余额（金币）是否充足

        Operator op = operatorService.getById(admin.getOperatorId());
        double balance = 0;
        Account account = accountService.getOne(new QueryWrapper<Account>().eq("operator_id",admin.getOperatorId()));
        if(account != null) {
            balance = BigDecimalUtils.sub(Double.parseDouble(account.getBalance()), amount);
        }else {
            balance = BigDecimalUtils.sub(Double.parseDouble(op.getGoldlimit()), amount);
        }
        if(balance >= 0 || payOrderInfo.getGoodsId() == 1 ||  payOrderInfo.getGoodsId() == 2 ||  payOrderInfo.getGoodsId() == 3){
            BaseDataResult result = suborder(amount, 3, payOrderInfo.getGoodsId(), payOrderInfo.getGoodsNum(), admin,payOrderInfo.getMac(), payOrderInfo.getSn());
            if(result.getCode().equals(Constans.SUCCESS)) {
                //分配用户授权码
                String orderNo = (String) result.getData();
                PayOrderInfo payOrderInfo1 = service.getOne(new QueryWrapper<PayOrderInfo>().eq("order_no",orderNo));
                Integer days = goods.getDays();
                Integer goodsNum = payOrderInfo1.getGoodsNum();
                Integer orderId = payOrderInfo1.getId();
                StringBuilder authCodeIds = new StringBuilder();
               // StringBuilder authCodes = new StringBuilder();
                //如果是创建账号
                if(StringUtils.isNotBlank(payOrderInfo.getMac()) && StringUtils.isNotBlank(payOrderInfo.getSn())){

                    DeviceInfo deviceInfo = new DeviceInfo();
                    deviceInfo.setMac(payOrderInfo.getMac());
                    deviceInfo.setSn(payOrderInfo.getSn());
                    deviceInfo.setExpired( days);
                    deviceInfo.setOperator(op.getName());
                    deviceInfo.setCreateTime(new Date());
                    deviceInfo.setType(2);
                    deviceInfo.setPayOrderInfoId(payOrderInfo1.getId());
                    deviceInfo.setStatus(0);
                    deviceInfoService.insert(deviceInfo);
                    payOrderInfo1.setServiceType(4);
                    service.updateById(payOrderInfo1);
                    return Result.OK();
                }else{
                    //自动生成激活码
                    for(int i=0;i<goodsNum;i++) {
                        String authCode = (int)((Math.random() * 9 + 1) * Math.pow(10, 6 - 1)) + "" + (int)((Math.random() * 9 + 1) * Math.pow(10, 6 - 1));
                        AuthCode user = new AuthCode();
                        user.setOperatorId(admin.getOperatorId());
                        user.setOrderId(orderId);
                        user.setAuthCode(authCode);
                        user.setDays(days);
                        user.setStatus(1);
                        user.setCreateTime(new Date());
                        user.setUpdateTime(new Date());
                        user.setComment(op.getName()+"购买"+goods.getName()+"订单："+orderNo);
                        int insertAc = authCodeService.insertAuthCode(user);
                        if(insertAc == 1) {
                            authCodeIds.append(user.getId()).append(",");
                            //    authCodes.append(authCode).append(",");
                        }
                    }
                    payOrderInfo.setAuthCodeIds(authCodeIds.toString());
                    service.updateById(payOrderInfo1);
                    return Result.OK();
                }

            }else{
                return Result.FAILURE(result.getCode(),result.getError());
            }
        }
       else {
            return Result.FAILURE (500, "余额不足!");
        }
    }
    @PostMapping("placeOrder2")
    @Transactional(rollbackFor = Exception.class)
    public Result placeOrder2(@RequestBody PayOrderInfo payOrderInfo, HttpServletRequest request){
        Admin admin = adminService.getById(StpUtil.getLoginIdAsInt());
        if(admin.getRoleId() != 5 && admin.getRoleId() != 3) {
            return Result.FAILURE("非经销商角色不能购买商品！");
        }
        //serviceType 订单服务类型：1.app充值;2.后台充值;3.购买商品
        Double price = 0.0;

        Goods goods =  goodsService.getById(payOrderInfo.getGoodsId());
        if( goods.getOrderId() ==1 || goods.getOrderId() ==2 || goods.getOrderId() ==3){
            return Result.FAILURE("免费商品不能充值！");
        }
        price =Double.parseDouble( goods.getPrice());
        Operator operator = operatorService.getById(admin.getOperatorId());
        if(admin.getRoleId() == 5){
            OperatorConfig occ = operatorConfigService.getOne(new QueryWrapper<OperatorConfig>().eq("goods_id", goods.getId()).eq("operator_id", admin.getOperatorId()));
            if(occ != null) {
                price = BigDecimalUtils.round(Double.parseDouble(goods.getPrice())*(1+ Float.parseFloat(operator.getGoodsrate())), 2);
            }
        }
        Double amount = BigDecimalUtils.mul(price, payOrderInfo.getGoodsNum());
        //查询用户账户余额（金币）是否充足

        Operator op = operatorService.getById(admin.getOperatorId());
        double balance = 0;
        Account account = accountService.getOne(new QueryWrapper<Account>().eq("operator_id",admin.getOperatorId()));
        if(account != null) {
            balance = BigDecimalUtils.sub(Double.parseDouble(account.getBalance()), amount);
        }else {
            balance = BigDecimalUtils.sub(Double.parseDouble(op.getGoldlimit()), amount);
        }
        if(balance >= 0 || payOrderInfo.getGoodsId() == 1 ||  payOrderInfo.getGoodsId() == 2 ||  payOrderInfo.getGoodsId() == 3){
            BaseDataResult result = suborder(amount, 3, payOrderInfo.getGoodsId(), payOrderInfo.getGoodsNum(), admin,payOrderInfo.getMac(), payOrderInfo.getSn());
            if(result.getCode().equals(Constans.SUCCESS)) {
                //分配用户授权码
                String orderNo = (String) result.getData();
                PayOrderInfo payOrderInfo1 = service.getOne(new QueryWrapper<PayOrderInfo>().eq("order_no",orderNo));
                Integer days = goods.getDays();
                Integer goodsNum = payOrderInfo1.getGoodsNum();
                //如果是创建账号
                if(StringUtils.isNotBlank(payOrderInfo.getMac())){

                    List<DeviceInfo> deviceInfos = deviceInfoService.selectDataList(new MPJLambdaWrapper<DeviceInfo>().eq(DeviceInfo::getMac, payOrderInfo.getMac()));
                    if(!deviceInfos.isEmpty()){
                        DeviceInfo deviceInfo = deviceInfos.get(0);
                        if(deviceInfo.getStatus() != 1 && deviceInfo.getStatus() != 3){
                            return Result.FAILURE (500, "只有 启用和授权到期 才能充值!");
                        }
                        if(deviceInfo.getStatus() == 1){
                            deviceInfo.setExpDate(DateUtils.addDays(deviceInfo.getExpDate(), days*goodsNum));
                        }

                        if(deviceInfo.getStatus() == 3){
                            deviceInfo.setStatus(1);
                            deviceInfo.setExpDate(DateUtils.addDays(new Date(), days*goodsNum));
                        }
                        try {
                            service.updateXUI(deviceInfo);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        boolean update = deviceInfoService.update(deviceInfo);
                        return update ? Result.OK() : Result.FAILURE();
                    }
                }

            }else{
                return Result.FAILURE(result.getCode(),result.getError());
            }
        }
        else {
            return Result.FAILURE (500, "余额不足!");
        }
        return Result.FAILURE();
    }
    public BaseDataResult suborder(Double amount, Integer serviceType, Integer goodsId, Integer goodsNum, Admin admin,String mac,String sn) {
        Integer operateId = admin.getId();
        Integer operatorId = admin.getOperatorId();
        String operatorName = admin.getOperatorName();
        Integer userId = 0;
        try {
            PreCreateResultVO result = null;
            if (amount == null) {
                return new BaseDataResult(Constans.FAILED, "订单金额不能为空！单位（金币）", result);
            }
            if (serviceType == null) {
                return new BaseDataResult(Constans.FAILED, "服务类型不能为空！1.app充值;2.后台充值;3.购买商品", result);
            }
            if (operatorId == null) {
                return new BaseDataResult(Constans.FAILED, "经销商ID不能为空！", result);
            }
            Operator operator =  operatorService.getById(operatorId);
            if (operator == null) {
                return new BaseDataResult(Constans.FAILED, "经销商查询为空！", result);
            }
            IDGenerator Id1 = new IDGenerator(1);
            String time = TimeUtils.converStringDate(new Date(), "yyMMdd");
            String orderNo = serviceType + time + Id1.nextId();
            PayOrderInfo order =  service.getOne(new QueryWrapper<PayOrderInfo>().eq("order_no",orderNo));
            // 判断订单号是否重复
            while (order != null) {
                orderNo = serviceType + time + Id1.nextId();
                order =  service.getOne(new QueryWrapper<PayOrderInfo>().eq("order_no",orderNo));
            }
            String subject = "购买授权码";
            PayOrderInfo payOrderInfo = new PayOrderInfo();
            payOrderInfo.setServiceType(serviceType);
            payOrderInfo.setGoodsId(goodsId);
            payOrderInfo.setGoodsNum(goodsNum);
            payOrderInfo.setMoney(amount.toString());
            payOrderInfo.setBalance("0");
            payOrderInfo.setOrderNo(orderNo);
            payOrderInfo.setMac( mac);
            payOrderInfo.setSn( sn);
            payOrderInfo.setCreateTime(TimeUtils.getCurrentTime());
            /** 订单状态（-1：未支付，0:支付成功，1已退款） */
            payOrderInfo.setStatus(0);
            /** (0：默认初始值，1支付失败，2退款失败，3申请退款) */
            payOrderInfo.setDetailState(0);
            payOrderInfo.setOperatorId(operatorId);// 默认
            //查询用户账户余额
            BigDecimal balance = BigDecimal.valueOf(0);
            Account account = accountService.getOne(new QueryWrapper<Account>().eq("operator_id",operatorId));
            //判断是否免费激活码且剩余额度是否够用
            Integer three = account!=null ? account.getThree() : operator.getThree();
            Integer seven = account!=null ? account.getSeven() : operator.getSeven();
            Integer thirty = account!=null ? account.getThirty() : operator.getThirty();
            //if(amount == 0) {
            if(payOrderInfo.getGoodsId() == 1 ||  payOrderInfo.getGoodsId() == 2 ||  payOrderInfo.getGoodsId() == 3) {
                Goods goods =  goodsService.getById(goodsId);
                if(goods != null) {
                    Integer days = goods.getDays();
                    if(days == 3) {
                        three = account!=null ? account.getThree()-goodsNum : operator.getThree()-goodsNum;
                        if(three < 0) {
                            return new BaseDataResult(Constans.FAILED, "三天免费授权码额度不足！", result);
                        }
                    }
                    if(days == 1) {
                        seven = account!=null ? account.getSeven()-goodsNum : operator.getSeven()-goodsNum;
                        if(seven < 0) {
                            return new BaseDataResult(Constans.FAILED, "一天免费授权码额度不足！", result);
                        }
                    }
                    if(days == 30) {
                        thirty = account!=null ? account.getThirty()-goodsNum : operator.getThirty()-goodsNum;
                        if(thirty < 0) {
                            return new BaseDataResult(Constans.FAILED, "三十天免费授权码额度不足！", result);
                        }
                    }
                }
            }
            if(account == null){
                balance = BigDecimal.valueOf(BigDecimalUtils.sub(0, amount));
                account = new Account();
                account.setOperatorId(payOrderInfo.getOperatorId());
                account.setBalance(balance.toString());
                account.setFreezeMoney("0");
                account.setCreateTime(new Date());
                account.setThree(three);
                account.setSeven(seven);
                account.setThirty(thirty);
                accountService.save(account);
            }else if(serviceType == 3) {
                balance = BigDecimal.valueOf(BigDecimalUtils.sub( Double.parseDouble(account.getBalance()), amount));
                account.setBalance(balance.toString());
                account.setThree(three);
                account.setSeven(seven);
                account.setThirty(thirty);
                accountService.updateById(account);
            }
            payOrderInfo.setBalance(balance.toString());
            if (StringUtils.isBlank(operatorName)) {
                if (null != operator) {
                    operatorName = operator.getName();
                }
            }
            payOrderInfo.setCreateBy(operateId);
            payOrderInfo.setOperateIp(admin.getLoginIp());
            //支付渠道(0.线下支付，1支付宝，2微信支付3贝宝支付4余额支付)
            payOrderInfo.setChannels(4);
            payOrderInfo.setPayTime(TimeUtils.getCurrentTime());
            boolean b = service.save(payOrderInfo);
            if (!b ) {
                return new BaseDataResult(Constans.FAILED, "提交订单失败！", result);
            }
            return new BaseDataResult(Constans.SUCCESS, "提交订单成功！", orderNo);
        } catch (Exception e) {
            e.printStackTrace();
            return new BaseDataResult(Constans.FAILED, "提交订单异常", e.getMessage());
        }
    }
}
